﻿using System.Collections.Generic;
using System.Drawing;
using NeuronDotNet.Controls;

namespace NeuronDotNet.Samples.OCR.layoutsstategies
{
  /// <summary>
  /// This Class realized one of drawing
  /// fields devide strategy. 
  /// </summary>
  public class DivisionBuilder : ILayoutStrategy
  {
    #region public property
    /// <summary>
    /// Current Letter.
    /// </summary>
    public Letter Letter { get; private set; }
    #endregion

    #region construtor for DivisionBuilder class
    /// <summary>
    /// Constructor. Takes one Letter as argument.
    /// </summary>
    public DivisionBuilder(Letter letter)
    {
      Letter = letter;
    }
    #endregion

    #region private methods
    /// <summary>
    /// Devide Drawing field apart.
    /// </summary>
    private List<Rectangle> ScanMap(Bitmap map)
    {
      var result = new List<Rectangle>();
      int width = 0;
      bool previousWhite = true;

      //In every column
      for (int i = 0; i < map.Width; i++)
      {
        bool isWhite = true;
        //Scan the pixels
        for (int j = 0; j < map.Height; j++)
        {
          //If we meet a colored pixel
          bool isColoredPixel = IsColoredPixel(map, i, j);
          if (isColoredPixel)
          {
            //found a new letter
            isWhite = false;
            previousWhite = false;
            width++;
            //continue to next column
            break;
          }
          //if we reach this, isWhite is true
        }
        //End of letter
        if (EndOfLetter(map,i,isWhite,previousWhite))
        {
          int start = i - width;
          result.Add(new Rectangle(start + Letter.left,
            Letter.top,
            width,
            map.Height));
          width = 0;
          previousWhite = true;
        }
      }
      return result;
    }
    /// <summary>
    /// Checks for conditions that indicate end of letter.
    /// </summary>
    /// <returns></returns>
    private static bool EndOfLetter(Bitmap map,
      int position,
      bool isWhite,
      bool previousWhite)
    {
      bool whiteColumnMet = isWhite && !previousWhite;
      bool letterTouchesBoundaries = (position == map.Width - 1) && !previousWhite;
      bool isPreviousWhiteOrENdOfMape = whiteColumnMet || letterTouchesBoundaries;
      return isPreviousWhiteOrENdOfMape;
    }
    /// <summary>
    /// Check is pixel colored.
    /// </summary>
    private static bool IsColoredPixel(Bitmap bitmap, int i, int j)
    {
      const int whiteInRGB = 255;
      bool isWhiteR = bitmap.GetPixel(i, j).R != whiteInRGB;
      bool isWhiteG = bitmap.GetPixel(i, j).G != whiteInRGB;
      bool isWhiteB = bitmap.GetPixel(i, j).B != whiteInRGB;
      return isWhiteR && isWhiteG && isWhiteB;
    }
    #endregion

    #region public method
    /// <summary>
    /// Scan the bitmap and create a list of rectangle wich related to letter
    /// </summary>
    public List<Rectangle> GetDivision()
    {
      Bitmap map = Letter.MakeBitmap();
      return ScanMap(map);
    }
    #endregion
  }
}
